<?php
declare(strict_types=1);

namespace App\Service;

use Hyperf\DbConnection\Db;
use App\Constants\ReturnCode;
use Throwable;
use App\Helper\Util;
use Qbhy\HyperfAuth\Annotation\Auth;
use Qbhy\HyperfAuth\AuthManager;
use Hyperf\Di\Annotation\Inject;
use App\Model\User;
use App\Service\StatisrecService;

/**
 * 登录服务
 */
class LoginService 
{
    /**
     * 登录方式
     * [$login_type description]
     * @var [type]
     */
    private $login_type = [
        'ap_code',
        'wx_code',
        'apple_code'
    ];
    #[Inject]
    protected AuthManager $auth;
    /**
     * 登录统一入口
     * [doLogin description]
     * @param  [type] $params [description]
     * @return [type]         [description]
     */
    public function doLogin($params)
    {
        if(empty($params['type']) || !in_array($params['type'], $this->login_type)){
            return ['status'=>0,'msg'=>'登录方式错误'];
        }
        switch ($params['type']) {
            case 'ap_code':
                $res = $this->loginByApCode($params);
                break;
            case 'wx_code':
                $res = $this->loginByWxCode($params);
                break;
            case 'apple_code':
                $res = $this->loginByAppleCode($params);
                break;
        }
        return $res;
    }
    /**
     * 小程序授权码登录
     * [loginByApCode description]
     * @param  [type] $params [description]
     * @return [type]         [description]
     */
    public function loginByApCode($params)
    {
        if(empty($params['code'])){
            return ['status'=>0,'msg'=>'code不能为空'];
        }
        $authinfo = $this->getApOpenIdByCode($params['code']);
        if(empty($authinfo['openid'])){
            return ['status'=>0,'msg'=>'授权登录失败'.$authinfo['errmsg']];
        }

        $user_info = User::query()
            ->select(
                'id',
                'wx_openid',
                'ap_openid',
                'unionid',
                'nickname',
                'avatar',
                'device',
                'realname',
                'phone',
                'login_num',
                'status',
                'is_del'
            )
            ->where(['ap_openid'=>$authinfo['openid']])
            ->first();
        //用户为空，需要授权phone
        if(empty($user_info)){
            $params['ap_openid'] = $authinfo['openid']??"";
            $params['unionid'] = $authinfo['unionid']??"";
        }

        $login_res = $this->unifyLogin($user_info,$params);
        return $login_res;
    }
    /**
     * 微信授权码登录
     * [loginByWxCode description]
     * @param  [type] $params [description]
     * @return [type]         [description]
     */
    public function loginByWxCode($params)
    {
        if(empty($params['code'])){
            return ['status'=>0,'msg'=>'code不能为空'];
        }
        $authinfo = $this->getWxOpenIdByCode($params['code']);
        if(empty($authinfo['openid']) || empty($authinfo['unionid'])){
            return ['status'=>0,'msg'=>'授权登录失败'.$authinfo['errmsg']];
        }

        $user_info = User::query()
            ->select(
                'id',
                'wx_openid',
                'ap_openid',
                'unionid',
                'nickname',
                'avatar',
                'device',
                'realname',
                'phone',
                'login_num',
                'status',
                'is_del'
            )
            ->where(['unionid'=>$authinfo['unionid']])
            ->first();
        //用户为空，需要授权phone
        if(empty($user_info)){
            $params['unionid'] = $authinfo['unionid']??"";
        }

        $login_res = $this->unifyLogin($user_info,$params);
        return $login_res;
    }
    /**
     * 苹果授权码登录
     * [loginByAppleCode description]
     * @param  [type] $params [description]
     * @return [type]         [description]
     */
    public function loginByAppleCode($params)
    {
        if(empty($params['code'])){
            return ['status'=>0,'msg'=>'code不能为空'];
        }
        $unionid = "APPLE_".$params['code'];

        $user_info = User::query()
            ->select(
                'id',
                'wx_openid',
                'ap_openid',
                'unionid',
                'nickname',
                'avatar',
                'device',
                'realname',
                'phone',
                'login_num',
                'status',
                'is_del'
            )
            ->where(['unionid'=>$unionid])
            ->first();
        //用户为空，需要授权phone
        if(empty($user_info)){
            $params['unionid'] = $unionid;
        }

        $login_res = $this->unifyLogin($user_info,$params);
        return $login_res;
    }
    /**
     * 统一创建登录
     * [unifyLogin description]
     * @param  [type] $user_info [description]
     * @param  [type] $params    [description]
     * @return [type]            [description]
     */
    public function unifyLogin($user_info,$params)
    {
        //用户异常状态判断
        //用户是否冻结
        if(!empty($user_info->status) && $user_info->status==2){
            return ['status'=>0,'msg'=>'登录失败，账户已冻结'];
        }
        //用户是否注销
        if(!empty($user_info->is_del) && $user_info->is_del==1){
            return ['status'=>0,'msg'=>'登录失败，账户已注销'];
        }

        //新用户注册并登录
        if(empty($user_info)){
            $insert_data = [
                'login_num' => 1,
                'login_time' => time(),
                'status' => 1,
                'is_del' => 0,
                'created_at' => time()
            ];
            if(!empty($params['wx_openid'])){
                $insert_data['wx_openid'] = $params['wx_openid'];
            }
            if(!empty($params['ap_openid'])){
                $insert_data['ap_openid'] = $params['ap_openid'];
            }
            if(!empty($params['unionid'])){
                $insert_data['unionid'] = $params['unionid'];
            }
            if(!empty($params['device'])){
                $insert_data['device'] = $params['device'];
            }
            $id = Db::table('user')->insertGetId($insert_data);
            if(!$id){
                return ['status'=>0,'msg'=>'登录失败'];
            }
            $user_info = User::query()
                ->select(
                    'id',
                    'wx_openid',
                    'ap_openid',
                    'unionid',
                    'nickname',
                    'avatar',
                    'device',
                    'realname',
                    'phone',
                    'login_num',
                    'status',
                    'is_del'
                )
                ->where(['id'=>$id])
                ->first();
            $staServ = new StatisrecService();
            $static_params = [
                'device'=>$params['device'],
                'tag'=>'reg',
                'save_type'=>'normal'
            ];
            $staServ->doSave($static_params);
        }else{
            $update_data = [
                'login_time' => time(),
                'updated_at' => time(),
                'login_num' => $user_info->login_num+1
            ];
            if(!empty($params['wx_openid'])){
                $update_data['wx_openid'] = $params['wx_openid'];
            }
            if(!empty($params['ap_openid'])){
                $update_data['ap_openid'] = $params['ap_openid'];
            }
            if(!empty($params['unionid'])){
                $update_data['unionid'] = $params['unionid'];
            }
            if(!empty($params['device'])){
                $update_data['device'] = $params['device'];
            }
            $res = Db::table('user')->where('id', $user_info['id'])->update($update_data);
            if(!$res){
                return ['status'=>0,'msg'=>'登录失败'];
            }
        }

        return $this->getLoginToken($user_info);
    }
    /**
     * 登录成功后获取token
     * [getLoginToken description]
     * @param  [type] $user_info [description]
     * @return [type]            [description]
     */
    public function getLoginToken($user_info)
    {
        var_dump($user_info);
        $token = $this->auth->guard('app')->login($user_info);
        $return_data = [
            'token' => $token
        ];
        return ['status'=>1,'msg'=>'登录成功','data'=>$return_data];
    }
    /**
     * 根据code获取小程序openid
     * [getApOpenIdByCode description]
     * @param  [type] $code [description]
     * @return [type]       [description]
     */
    public function getApOpenIdByCode($code)
    {
        $wxconfig = config('wxconfig', []);
        $apconfig = $wxconfig['mini_program']??[];
        $appid = $apconfig['appid']??NULL;
        $appsecret = $apconfig['appsecret']??NULL;
        $authinfo = Util::getApOpenIdByCode($code,$appid,$appsecret);
        return $authinfo;
    }
    /**
     * 根据code获取微信openid
     * [getWxOpenIdByCode description]
     * @param  [type] $code [description]
     * @return [type]       [description]
     */
    public function getWxOpenIdByCode($code)
    {
        $wxconfig = config('wxconfig', []);
        $apconfig = $wxconfig['app_qpp']??[];
        $appid = $apconfig['appid']??NULL;
        $appsecret = $apconfig['appsecret']??NULL;
        $authinfo = Util::getWxOpenIdByCode($code,$appid,$appsecret);
        return $authinfo;
    }

}
